package com.bw.goods.controller;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bw.goods.domain.Dishes;
import com.bw.goods.domain.DishesSss;
import com.bw.goods.domain.ShopCar;
import com.bw.goods.domain.User;
import com.bw.goods.service.DishesService;
import com.bw.goods.service.DishesSssService;
import com.bw.goods.service.ShopCarService;
import com.bw.goods.units.Result;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/dishes")
public class DishesController {
    @Autowired
    private DishesService dishesService;
    @Autowired
    private DishesSssService dishesSssService;
    @Autowired
    private ShopCarService shopCarService;
    @Autowired
    private RedisTemplate redisTemplate;
    @RequestMapping("/list/{tid}")
    public Result list(@PathVariable Integer tid){
        LambdaQueryWrapper<DishesSss> dishesLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishesLambdaQueryWrapper.eq(DishesSss::getTid,tid);
        List<DishesSss> list = dishesSssService.list(dishesLambdaQueryWrapper);
        return Result.success(list);
    }
    @RequestMapping("/list")
    public Result dlist(Integer current,Integer size){
        PageHelper.startPage(current,size);
        List<DishesSss> list = dishesSssService.list();
        return Result.success(new PageInfo<>(list));
    }
    @RequestMapping("/tlist")
    public Result tlist(){
        List<Dishes> list = (List<Dishes>) redisTemplate.opsForValue().get("tylist");
        System.out.println("dsdvsd"+list);
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都有默认值的
        treeNodeConfig.setWeightKey("order");
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setNameKey("name");
//        // 最大递归深度
//        treeNodeConfig.setDeep(3);
        //转换器 (含义:找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
        List<Tree<String>> treeNodes = TreeUtil.<Dishes, String>build(list, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId()+"");
                    tree.setParentId(treeNode.getPid()+"");
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
                    tree.putExtra("component", treeNode.getComponent());
                    tree.putExtra("path", treeNode.getPath());
                });
        return Result.success(treeNodes);
    }
    @RequestMapping("/tylist")
    public Result tylist() throws InterruptedException {
        Thread.sleep(2000);
        if(!redisTemplate.hasKey("tylist")){
            List<Dishes> list = dishesService.list();
            redisTemplate.opsForValue().set("tylist",list);
        }
        List<Dishes> tylist = (List<Dishes>) redisTemplate.opsForValue().get("tylist");
        return Result.success(tylist);
    }
//    @RequestMapping("/add")
    public Result add(@RequestBody ShopCar dishes, HttpServletRequest request){
        String token = request.getHeader("token");
        Claims claims = JwtUtils.parseToken(token);
        Integer id = (Integer) claims.get("id");
        System.out.println("---------------id,dv"+id);
        System.out.println("ncdncjdnjc0"+dishes);
        String remoteAddr = request.getRemoteAddr();
        String s = DigestUtil.md5Hex(dishes.toString() + remoteAddr);
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(s, "1", 2, TimeUnit.SECONDS);
        if(!aBoolean){
            return Result.fail("不可以频繁下单，限制2秒一次");
        }
        dishes.setId(null);
        //redis记录每个菜品的下单数量
        Long increment = redisTemplate.opsForValue().increment(dishes.getName(), 1);
        Long increment1 = redisTemplate.opsForValue().increment(id, 1);
        redisTemplate.expire(dishes.getName()+id,24,TimeUnit.HOURS);
        //19.每个用户每天最多只能下三单，实现方式考生自主选择（5分）
        if(increment1>3){
            return Result.fail("每个用户每天最多只能下三单");
        }
        boolean save = shopCarService.save(dishes);
        return save?Result.success():Result.fail();
    }
    @RequestMapping("/gocar")
    public Result gocar(Integer current,Integer size){

        List<ShopCar> list;
        if (current == 1 && redisTemplate.hasKey("shoulist")) {
            // 如果是第一页且 Redis 中存在第一页的数据，则从 Redis 中获取
            List<ShopCar> listx = (List<ShopCar>) redisTemplate.opsForList().range("shoulist", 0, -1);
            return Result.success(new PageInfo<>(listx));
        } else {
            PageHelper.startPage(current, size);
            LambdaQueryWrapper<ShopCar> shopCarLambdaQueryWrapper = new LambdaQueryWrapper<>();
            shopCarLambdaQueryWrapper.eq(ShopCar::getDel, 0);
            // 否则从数据库获取数据
            list = shopCarService.list(shopCarLambdaQueryWrapper);
            // 如果是第一页，则将数据存入 Redis
            if (current == 1 && !redisTemplate.hasKey("shoulist")) {
                redisTemplate.opsForList().leftPushAll("shoulist", list);
            }
        }
        return Result.success(new PageInfo<>(list));
    }
    @RequestMapping("/check/{id}")
    public Result check(@PathVariable Integer id){
        ShopCar byId = shopCarService.getById(id);
        byId.setStatus("已审批");
        shopCarService.updateById(byId);
        return Result.success();
    }
    @RequestMapping("/del/{id}")
    public Result del(@PathVariable Integer id){
        boolean b = shopCarService.removeById(id);
        return b?Result.success():Result.fail();
    }


    @Autowired
    private HttpServletRequest request;
    /**
     * 购物车
     */
    @RequestMapping("/add")
    public Result add(String dishesInfo,@RequestParam(value = "num",defaultValue = "1") Integer num,@RequestParam(value = "from",defaultValue = "")String from){
        Claims token = JwtUtils.parseToken(request.getHeader("token"));
        Integer uid = (Integer) token.get("id");
        if("cart".equals(from)){
            redisTemplate.opsForHash().put("cart:"+uid,dishesInfo,num);
            return Result.success();
        }
        //其他来源加入购物车，如果购物车存在则在原来的数据上加num
        Integer oldNum = (Integer) redisTemplate.opsForHash().get("cart:" + uid, dishesInfo);
        if(oldNum!=null){
            num+=oldNum;
        }
        redisTemplate.opsForHash().put("cart:"+uid,dishesInfo,num);
        return Result.success();
    }

    /**
     * 我的购物车
     */
    @RequestMapping("/mycart")
    public Result mycart(){
        Claims token = JwtUtils.parseToken(request.getHeader("token"));
        Integer uid = (Integer) token.get("id");
        Map<Integer,Integer> cartMap = redisTemplate.opsForHash().entries("cart:" + uid);
        if(cartMap==null || cartMap.isEmpty()){
            return Result.success();
        }
        //查询商品信息
        Set<Integer> integers = cartMap.keySet();
        LambdaQueryWrapper<DishesSss> dishesSssLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishesSssLambdaQueryWrapper.in(DishesSss::getDishesInfo,integers);
        List<DishesSss> list = dishesSssService.list(dishesSssLambdaQueryWrapper);
        list.forEach(dishes->{
            //计算小计
            dishes.setNum(cartMap.get(dishes.getDishesInfo()));
            dishes.setTotal(dishes.getPrice().multiply(new BigDecimal(dishes.getNum()+"")));
        });
        //计算总计
        double sum = list.stream().mapToDouble(item -> item.getTotal().doubleValue()).sum();
        //返回结果
        Map<String, Object> map = new HashMap<>();
        map.put("cartlist",list);
        map.put("total",sum);
        return Result.success(map);
    }

}
